﻿using System.ComponentModel;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;
using VNet.VisiSuite.Common;
using VNet.VisiSuite.Common.Helper;
using VNet.VisiSuite.Common.Logger;
using VNet.VisiSuite.Common.Resource;
using VNet.VisiSuite.Common.Security;
using VNet.VisiSuite.Controls;
using VNet.VisiSuite.Service.Contact.Message;
using VNet.VisiSuite.Service.Contact.Message.Base;
using VNet.VisiSuite.Service.Contact.Message.Item;
using VNet.VisiSuite.Service.Contact.Message.Security;
using VNet.VisiSuite.VisiBoard.BusinessLogic;
using VNet.VisiSuite.VisiBoard.Common;
using VNet.VisiSuite.VisiBoard.Common.Helpers;
using VNet.VisiSuite.VisiBoard.Models;
using VNet.VisiSuite.VisiBoard.Providers;
using VNet.VisiSuite.VisiBoard.Views;

namespace VNet.VisiSuite.VisiBoard.ViewModels
{
    public class ConfigurationViewModel : BaseViewModel
    {
        #region Fields
        private ConfigurationModel _model;
        private Visibility _visibility;
        private bool _cellExisted;
        #endregion

        public ConfigurationViewModel()
        {
            
            ConfigureCommand = new RelayCommand(DoConfigure);

            PageTitle = TitleString.ConfigurationViewBoardTitle;
            TopRightButtonIcons = new ObservableCollection<VNetMenuItem> { new VNetMenuItem("Exit", "Exit VisiSuite", CommonConstants.VNetIcon.AppbarClose, VNetMenuItemType.WhiteBackgroundTheme, OnExit), };
        }

        #region Properties
        public RelayCommand ConfigureCommand { get; set; }

        public ConfigurationModel Model
        {
            get { return _model; }
            set
            {
                _model = value;
                OnPropertyChanged("Model");
            }
        }

        public Visibility Visibility
        {
            get { return _visibility; }
            set
            {
                _visibility = value;
                OnPropertyChanged("Visibility");
            }
        }

        public bool CellExisted
        {
            get { return _cellExisted; }
            set
            {
                _cellExisted = value;
                OnPropertyChanged("CellExisted");
            }
        }

        #endregion

        #region Methods
        private void DoConfigure(object obj)
        {
            if (!Model.IsValid())
                return;

            IsBusy = true;
            ErrorMessage = string.Empty;
            StatusMessage = "Verifying cell...";

            var sync_data = new SyncProvider.SyncProviderData
            {
                CellId = Model.CellId,
                Password = Model.Password,
                InstallKey = Model.InstallKey,
                ServiceUrl = Model.ServiceUrl,
                TablesChanges = null // this means get all tables
            };
            DoAsync(SyncProvider.VerifyCellAndGetServerData, ConfigureCompleted, sync_data);
        }

        private void ConfigureCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            var result = (ConfigureResponse)e.Result;

            if (!result.Success) // && result.Error != null && (result.Error.ErrorCode == "Error InstallKey" || result.Error.Description == ErrorMessages.ServiceUrlInvalid))
            {
                DisplayRegistryFields(Visibility.Visible, Model.InstallKey.TrimSafety(), Model.ServiceUrl.TrimSafety());
                //RegistryHelper.DeleteInstallKeyRegistry();
                CellExisted = false;
                ErrorMessage = result.Error.Description;
                IsBusy = false;
            }
            else
            {
                RegistryKey reg = RegistryHelper.OpenRegistryVisi(CommonConstants.RegistryVisiSuite, true);
                reg.SetValue(CommonConstants.RegistryInstallKey, Model.InstallKey.TrimSafety());
                reg.SetValue(CommonConstants.RegistryServiceUrl, Model.ServiceUrl.TrimSafety());
                reg.Close();

                //App.DownloadLogoImage();
                DisplayRegistryFields(Visibility.Collapsed, Model.InstallKey.TrimSafety(), Model.ServiceUrl.TrimSafety());

                StatusMessage = "Synchronizing data from server...";
                DoAsync(LocalProvider.SyncDataFromServerToClient, SyncDataFromServerToClientCompleted, result);
            }

        }

        private void SyncDataFromServerToClientCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {

            var response = ((ServiceBaseResponse)e.Result).Success;

            if (!response)
            {
                IsBusy = false;
                MessageBox.Show("Error");
                return;
            }

            StatusMessage = "Synchronizing data to server...";
            var local_util = new LocalUtil();
            var pre_sync_response = ClientSyncUtil.PreSyncFromClientToServer();
            if (!pre_sync_response.Success)
            {
                IsBusy = false;
                MessageBox.Show("Error at prepare data to sync from client :" + pre_sync_response.Error.Description);
                return;
            }

            if (NavigationManager.CurrentCell == null)
            {
                // On first login, password is changed, so we need to get it from the database again.
                var cell = local_util.GetLocalCell();
                if (cell.Success && cell.Data.Password != Model.Password)
                {
                    Model.CellId = cell.Data.CellId;
                    Model.Password = cell.Data.Password;
                }

                NavigationManager.CurrentCell = new CellItem
                {
                    CellId = Model.CellId,
                    Password = Model.Password
                };
            }

            DoAsync(SyncProvider.SyncDataFromClientToServer1, SyncDataFromClientToServerCompleted, pre_sync_response.Data);
                
        }

        private void SyncDataFromClientToServerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            var response = ((ServiceBaseResponse)e.Result).Success;
            IsBusy = false;
            if (!response)
            {
                MessageBox.Show("Error at SyncDataFromClient:" +((ServiceBaseResponse)e.Result).Error.Description);
                NavigationManager.NavigateTo(new ProductionView(), null);
                return;
            }

            var local_util = new LocalUtil();
            var post_sync_response = ClientSyncUtil.PostSyncFromClientToServer(e.Result as SyncDataFromClientResponse);

            if (!post_sync_response.Success)
            {
                MessageBox.Show("Error at prepare data to sync from client :" + post_sync_response.Error.Description);
                return;
            }

            StatusMessage = "Sychronization complete...";

            NavigationManager.NavigateTo(new ProductionView(), null);
        }

        
        private void GetLocalCellCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {

            var response = (GetDataResponse<CellItem>)e.Result;
            if (response == null || !response.Success)
            {
                IsBusy = false;
                ErrorMessage = response.Error.Description;
                return;
            }

            var cellItem = response.Data;
            IsBusy = CellExisted = cellItem != null;

            if (CellExisted)
            {
                Model.Password = response.Data.Password;
                Model.CellId = response.Data.CellId;
                DoConfigure(null);
            }
        }

        private void DisplayRegistryFields(Visibility visibility, string key = "", string url = "")
        {
            if (Model == null)
                return;

            Visibility = visibility;
            Model.InstallKey = key;
            Model.ServiceUrl = url;
        }

        private void OnExit()
        {
            NavigationManager.CloseProgram();
        }

        #endregion

        #region Navigation Framwork
        public override void OnNavigate(object obj)
        {
            Model = new ConfigurationModel();
            Visibility = Visibility.Collapsed;
            CellExisted = true;

            //Check registry for CustomeURL
            if (!RegistryHelper.CheckRegistryInstallKeyExist())
            {
                DisplayRegistryFields(Visibility.Visible);
            }
            else
            {
                var reg = RegistryHelper.OpenRegistryVisi(CommonConstants.RegistryVisiSuite, false);
                DisplayRegistryFields(Visibility.Collapsed, reg.GetValue(CommonConstants.RegistryInstallKey).ToString(), reg.GetValue(CommonConstants.RegistryServiceUrl).ToString());
                reg.Close();
            }
            Model.ShouldValidate = true;

#if DEBUG
            Model.Password = "12345";
#endif

            IsBusy = true;
            DoAsync(LocalProvider.GetLocalCell, GetLocalCellCompleted);
        }

        public override void OnLeave()
        {
        }
        #endregion
    }
}
